package com.itheima.sh.a_jdbc_test01;

import com.itheima.sh.util.JDBCUtils01;
import com.mysql.jdbc.Driver;
import org.junit.Test;

import java.sql.*;

public class JDBCTest01 {
    //测试
    @Test
    public void test01() throws Exception {
        /*
            1.注册驱动
            使用驱动管理类：DriverManager中的静态方法。
            static void registerDriver(Driver driver) 向 DriverManager 注册给定驱动程序。
                参数：driver 属于java.sql.Driver的接口类型，表示每个驱动程序类必须实现的接口。
                这里是mysql数据库厂商定义实现类实现该接口。
                我们这里需要使用数据库厂商的驱动类，并创建对象，因为java.sql.Driver的接口不能创建对象
                数据库厂商提供的java.sql.Driver的接口实现类是：com.mysql.jdbc.Driver类
                public class com.mysql.jdbc.Driver  implements java.sql.Driver {}
            注意：
            1.开发不使用这种注册驱动的方式原因是注册了两次。
            当我们执行代码：
            DriverManager.registerDriver(new Driver());
            这里使用到了com.mysql.jdbc.Driver类。
            public class com.mysql.jdbc.Driver  implements java.sql.Driver {
            //类加载方法区就执行
             static {
                try {
                    //注册驱动
                    DriverManager.registerDriver(new Driver());
                } catch (SQLException var1) {
                    throw new RuntimeException("Can't register driver!");
                }
            }
            }
         */
//        DriverManager.registerDriver(new Driver());
        //使用反射技术让com.mysql.jdbc.Driver类加载到内存中就执行静态代码块
        Class.forName("com.mysql.jdbc.Driver");
        /*
            2.获取和数据库的连接
            使用DriverManager类调用静态方法：
            static Connection getConnection(String url, String user, String password) 试图建立到给定数据库 URL 的连接。
                参数：
                    url：表示连接数据库的地址。
                        jdbc:mysql://连接数据库服务器的ip地址:数据库的端口号/数据库名
                    user：连接数据库的用户名 root
                    password：连接数据库密码 1234
               返回值：Connection 连接接口
         */
        // url：表示连接数据库的地址。
        String url = "jdbc:mysql://localhost:3306/day06_113";
        //  user：连接数据库的用户名 root
        String user = "root";
        //  password：连接数据库密码 1234
        String password = "1234";
        Connection conn = DriverManager.getConnection(url, user, password);
        //conn = com.mysql.jdbc.JDBC4Connection@6c629d6e
//        System.out.println("conn = " + conn);
        /*
            3.根据连接对象调用方法获取发送sql语句对象
            使用连接接口Connection中的方法：
             Statement createStatement() 创建一个 Statement 对象来将 SQL 语句发送到数据库。
             返回值：Statement表示向数据库发送sql语句的接口
         */
        Statement st = conn.createStatement();
        /*
            4.发送sql语句
            使用Statement接口中的方法发送：
                1. int executeUpdate(String sql) 执行给定 SQL 语句，该语句可能为 INSERT、UPDATE 或 DELETE 语句，
                                                或者不返回任何内容的 SQL 语句（如 SQL DDL 语句）。
                                 参数：sql 表示操作数据库的DML或者DDL语句
                                 返回值：(1) 对于 SQL 数据操作语言 (DML) 语句，返回行计数 (2) 对于什么都不返回的 SQL 语句，返回 0
               2. ResultSet executeQuery(String sql) 执行给定的 SQL 语句，该语句返回单个 ResultSet 对象。
                                参数：DQL语句
                                返回值：ResultSet表示接收查询的结果集接口
               3.boolean execute(String sql) 执行任何的sql语句 了解
         */
        //需求1：发送insert语句
//        String sql = "insert into user values(null,'柳岩','1234')";
//        int count = st.executeUpdate(sql);
//        System.out.println("count = " + count);
        //需求2：发送修改语句
//        int count2 = st.executeUpdate("UPDATE user SET username='杨幂',password='4567' WHERE id=4");
//        System.out.println("count2 = " + count2);
//        //需求3：发送删除语句
//        int count3 = st.executeUpdate("delete from user where id=4");
//        System.out.println("count3 = " + count3);


        /*
           2. ResultSet executeQuery(String sql) 执行给定的 SQL 语句，该语句返回单个 ResultSet 对象。
                                参数：DQL语句
                                返回值：ResultSet表示接收查询的结果集接口
         */
        String sql = "SELECT id,username,password AS pwd FROM user";
        ResultSet rs = st.executeQuery(sql);
        /*
            5.处理结果集
         */
        while (rs.next()) {
            //说明结果集有数据
            //获取数据
            int id = rs.getInt(1);//1表示id位于第一列
            String username = rs.getString("username");//username表示表的字段名
            String pwd = rs.getString("pwd");//pwd表示别名
            System.out.println(id + "---" + username + "---" + pwd);
        }
    }


    //测试
    @Test
    public void test02() {
        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;
        try {
            //使用反射技术让com.mysql.jdbc.Driver类加载到内存中就执行静态代码块
//            Class.forName("com.mysql.jdbc.Driver");
            // url：表示连接数据库的地址。
            String url = "jdbc:mysql://localhost:3306/day06_113";
            //  user：连接数据库的用户名 root
            String user = "root";
            //  password：连接数据库密码 1234
            String password = "1234";
            conn = DriverManager.getConnection(url, user, password);
            st = conn.createStatement();
            String sql = "SELECT id,username,password AS pwd FROM user";
            rs = st.executeQuery(sql);
        /*
            5.处理结果集
         */
            while (rs.next()) {
                //说明结果集有数据
                //获取数据
                int id = rs.getInt(1);//1表示id位于第一列
                String username = rs.getString("username");//username表示表的字段名
                String pwd = rs.getString("pwd");//pwd表示别名
                System.out.println(id + "---" + username + "---" + pwd);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //6.释放资源
            try {
                //判断是否为空
                if (rs != null) {
                    rs.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }

            try {
                //判断是否为空
                if (st != null) {
                    st.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                //判断是否为空
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    /*
         需求: 删除id=3的记录。
     */
    @Test
    public void test03(){
        Connection conn = null;
        Statement st = null;
        try {
            //1.使用工具类获取连接
            conn = JDBCUtils01.getConnection();
            //2.获取发送sql语句对象
            st = conn.createStatement();
            //3.发送sql语句
            int count = st.executeUpdate("DELETE FROM user WHERE id=2");
            System.out.println("count = " + count);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //4.释放资源
            JDBCUtils01.release(conn,st,null);
        }
    }

    /*
        jdbc控制事务
        需求：a给b转账100元
        a-100
        b+100
     */
    @Test
    public void test04(){
        Connection conn = null;
        Statement st = null;
        try {
            //1.获取连接
            conn = JDBCUtils01.getConnection();
            //2.手动开启事务
            conn.setAutoCommit(false);
            //3.获取发送sql语句的对象
            st = conn.createStatement();
            //4.发送sql语句
            // a-100
            int count1 = st.executeUpdate("UPDATE account SET money=money-100 WHERE name='a'");
            System.out.println("count1 = " + count1);

            //模拟异常
            int x = 1 / 0;

            //b+100
            int count2 = st.executeUpdate("UPDATE account SET money=money+100 WHERE name='b'");
            System.out.println("count2 = " + count2);
            //提交事务
            conn.commit();
        } catch (Exception e) {
            e.printStackTrace();
            //回滚事务
            try {
                //判断是否等于null
                if(conn!=null){
                    conn.rollback();
                }
            } catch (SQLException e1) {
                e1.printStackTrace();
            }

        } finally {
            //释放资源
            JDBCUtils01.release(conn,st,null);
        }
    }
}
